//8位 移位相加乘法器
//设计者：FPGA研究者
 //时间：2022年7月28日
/* 
//方法一：
module shifta(r,l,e,clk,q); //shifta子模块
    input [7:0] r;
	 input l,e,clk;
	 output reg [15:0] q;
	 integer k;
	 wire [15:0] r16;
	 assign r16={{8{1'b0}},r};
	 always@(posedge clk) 
	  begin if(l) q<=r16;
	   else if(e) begin 
		      q[0]<=1'b0;
				for(k=1;k<16;k=k+1) 
				  q[k]<=q[k-1];
       end
	 end
	endmodule	 
	
	
	
module shiftb(r,l,e,clk,q0,z); //shiftb子模块
    input [7:0] r;
	 input l,e,clk;
	 output  q0,z;
	 reg [7:0] q;
	 integer k;

	 always@(posedge clk) 
	  begin if(l) q<=r;
	   else if(e) begin 
				for(k=7;k>0;k=k-1) 
				  q[k-1]<=q[k];
			q[7]<=1'b0;
       end
		end
	assign z=(q==0);
	assign q0=q[0];
	endmodule

module sum(a,p,psel,sum); //sum子模块
   input [15:0] a,p;
   input psel;
   output [15:0] sum;
   reg [15:0] sum;
   wire [15:0] ap_sum;
   integer k;
	assign ap_sum=a+p;
	always@(psel or ap_sum)
	begin sum=psel?ap_sum:16'b0; end
	endmodule
	
module reg16(r,clk,rst,e,q);//寄存器模块
   input [15:0] r;
	input clk,rst,e;
	output reg [15:0] q;
	always@(posedge clk or negedge rst)
	begin if(!rst) q<=0;
	      else if(e)
			   q<=r;
	end
	endmodule
	
module multshift_cntrl(clock,reset,s,z,b0,ea,eb,ep,psel,done);//控制模块
    input clock,reset,s,z,b0;
	 output reg done;
	 output reg ea,eb,ep,psel;
	 reg [1:0] t,y;
	 parameter S1=2'b00,S2=2'b01,S3=2'b10;
	 
always@(s,t,z) 
   begin:state_table
	  case(t)
	    S1:if(s==0) y=S1; else y=S2;
		 S2:if(z==0) y=S2; else y=S3;
		 S3:if(s==1) y=S3; else y=S1;
		default:y=2'bxx;
	endcase
   end
	
always@(posedge clock or negedge reset) 
   begin:state_flipflops
    if(!reset) t<=S1;
	 else t<=y;
    end

always@(s,t,b0)
 begin:fsm_outputs
  ea=0;eb=0;done=0;psel=0;
  case(t)
    S1:ep=1;
	 S2:begin ea=1;eb=1;psel=1; if(b0) ep=1;else ep=0;end
	 S3:done=1;
	endcase
	end
endmodule


module shift_mux(clk,a,b,la,lb,reset,start,out,done);
    input clk,la,lb,reset,start;
    input [7:0] a,b;
    output 	 done ;
	 output  [15:0]out;
	 wire [15:0] tempa,tempb,out1;
	 wire q0,z0,done1;
	shifta u1(.r(a),.l(la),.e(1),.clk(clk),.q(tempa)); 
	shiftb u2(.r(b),.l(lb),.e(1),.clk(clk),.q0(q0),.z(z0));
   multshift_cntrl u3(.clock(clk),.reset(reset),.s(start),.z(z0),.b0(q0),.ea(),.eb(),.ep(),.psel(),.done(done1));
	sum u4(.a(tempa),.p(out1),.psel(psel),.sum(tempb));
	reg16 u5(.r(tempb),.clk(clk),.rst(rseet),.e(1),.q(out1));
	
   assign out=out1;
	assign done=done1;
endmodule	
*/	 

//方法二：乘法器
module shift_mux(out,opa,opb,clk,clr);
    input clk,clr;
	 input [7:0] opa,opb;
	 output reg[15:0]  out;
	// wire [15:0] sum;
	 
 function [15:0] mult;
     input [7:0] opa,opb;
	  reg [15:0] result;
	  integer i; 
	  begin 
	   result=opa[0]?opb:0;//为寄存器赋初值
	  for(i=1;i<8;i=i+1)
	  begin if(opa[i]) result=result+(opb<<i);end 
	  mult=result;
	  end
	  endfunction
	   
	//assign sum=mult(opa,opb)+out; 
	always@(posedge clk or posedge clr) 
	 begin if(clr) out<=0;
	       else out<=mult(opa,opb);
	 end
endmodule


